`timescale 1ns / 1ps
/******************************************************************************
*                                                                             *
* UTICA softcore v0.1                                                         *
*                                                                             *
* Copyright (c) 2012 Andrew D. Zonenberg                                      *
* All rights reserved.                                                        *
*                                                                             *
* Redistribution and use in source and binary forms, with or without modifi-  *
* cation, are permitted provided that the following conditions are met:       *
*                                                                             *
*    * Redistributions of source code must retain the above copyright notice  *
*      this list of conditions and the following disclaimer.                  *
*                                                                             *
*    * Redistributions in binary form must reproduce the above copyright      *
*      notice, this list of conditions and the following disclaimer in the    *
*      documentation and/or other materials provided with the distribution.   *
*                                                                             *
*    * Neither the name of the author nor the names of any contributors may be*
*      used to endorse or promote products derived from this software without *
*      specific prior written permission.                                     *
*                                                                             *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN     *
* NO EVENT SHALL THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT,         *
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    *
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   *
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY       *
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT         *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF    *
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.           *
*                                                                             *
******************************************************************************/

/**
	@file HardwareTestbench_EthernetInterface.v
	@author Andrew D. Zonenberg
	@brief Top-level module for testing ENCx24J600 and Ethernet interface
 */
module HardwareTestbench_EthernetInterface(
	clk_20mhz,
	enc_cs, enc_rd, enc_wrl, enc_wrh, enc_addr, enc_data, enc_int_n,
	buttons, leds, gpio, uart_rx, uart_tx
    );

	////////////////////////////////////////////////////////////////////////////////////////////////
	// IO declarations

	//Clocking
	input wire clk_20mhz;
	
	//Ethernet controller bus	
	output wire enc_cs;
	output wire enc_rd;
	output wire enc_wrl;
	output wire enc_wrh;
	output wire[14:0] enc_addr;
	inout wire[15:0] enc_data;
	input wire enc_int_n;
	
	//Debug stuff
	input wire[3:0] buttons;
	output reg[7:0] leds = 0;
	output reg[19:0] gpio = 0;
	input wire uart_rx;
	output wire uart_tx;
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Clock management
	wire clk;
	wire main_clk_pll_reset;
	wire main_clk_pll_locked;
	
	//TODO: real reset here!
	assign main_clk_pll_reset = 0;
	
	CoreClockManagement clkmgr (
		.clk_20mhz(clk_20mhz), 
		.clk(clk), 
		.main_clk_pll_reset(main_clk_pll_reset), 
		.main_clk_pll_locked(main_clk_pll_locked)
		);
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Debounce the buttons
	
	wire[3:0] buttons_debounced;
	
	SwitchDebouncerBlock #(.WIDTH(4), .INIT_VAL(4'b0000))
		debouncers(.clk(clk), .buttons(buttons), .buttons_debounced(buttons_debounced));
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Global set/reset
	
	STARTUP_SPARTAN6 STARTUP_SPARTAN6_inst (
		.GSR(buttons_debounced[3])		//when button 3 is pressed, do a soft reset
		//.CFGCLK(CFGCLK),       // 1-bit output: Configuration logic main clock output.
		//.CFGMCLK(CFGMCLK),     // 1-bit output: Configuration internal oscillator clock output.
		//.EOS(EOS),             // 1-bit output: Active high output signal indicates the End Of Configuration.
		//.CLK(CLK),             // 1-bit input: User startup-clock input
		//.GTS(GTS),             // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
		//.KEYCLEARB(KEYCLEARB)  // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
		);
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Layer 1 - NIC driver
	
	wire ready;
	
	wire cmd_enable;
	wire[3:0] cmd_opcode;
	wire[15:0] cmd_data_in;
	wire cmd_busy;
	wire[15:0] cmd_data_out;
	wire cmd_data_valid;
	
	wire link_state_interrupt;
	wire link_state;
	wire duplex_state;
	
	wire packet_ready;
	
	ENCx24Controller layer1_nicdriver (
		.clk(clk), 
		
		.ready(ready),
		
		.cmd_enable(cmd_enable), 
		.cmd_opcode(cmd_opcode), 
		.cmd_data_in(cmd_data_in), 
		.cmd_busy(cmd_busy), 
		.cmd_data_out(cmd_data_out), 
		.cmd_data_valid(cmd_data_valid),

		.enc_cs(enc_cs), 
		.enc_rd(enc_rd), 
		.enc_wrl(enc_wrl), 
		.enc_wrh(enc_wrh), 
		.enc_addr(enc_addr), 
		.enc_data(enc_data), 
		.enc_int_n(enc_int_n),
		
		//.uart_tx(uart_tx),
		//.uart_rx(uart_rx),
		.start(buttons_debounced[0]),
		
		.link_state_interrupt(link_state_interrupt),
		.link_state(link_state),
		.duplex_state(duplex_state),
		
		.packet_ready(packet_ready)
		);
		
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Layer 2 - Ethernet interface logic

	wire null_packet_ready;
	wire null_read_word;
	wire[15:0] null_rx_data;
	wire null_rx_rdy;
	wire null_read_done;

	EthernetInterface layer2_controller (
		.clk(clk), 
		
		.nic_ready(ready),
		.cmd_enable(cmd_enable), 
		.cmd_opcode(cmd_opcode), 
		.cmd_data_in(cmd_data_in), 
		.cmd_busy(cmd_busy), 
		.cmd_data_out(cmd_data_out), 
		.cmd_data_valid(cmd_data_valid), 
		.link_state_interrupt(link_state_interrupt), 
		.link_state(link_state), 
		.duplex_state(duplex_state), 
		.packet_ready(packet_ready),
		
		.null_packet_ready(null_packet_ready), 
		.null_read_word(null_read_word), 
		.null_rx_data(null_rx_data), 
		.null_rx_rdy(null_rx_rdy), 
		.null_read_done(null_read_done),
		
		.uart_tx(uart_tx),
		.uart_rx(uart_rx)
		);
		
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Layer 3 - protocol drivers
	
	NullPacketSink layer3_nullsink (
		.clk(clk), 
		.packet_ready(null_packet_ready), 
		.read_word(null_read_word), 
		.rx_data(null_rx_data), 
		.rx_rdy(null_rx_rdy), 
		.read_done(null_read_done)
		);
		
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Debug LEDs
	always @(posedge clk) begin
		leds[0] <= ready;
		leds[1] <= link_state;
		leds[2] <= duplex_state;
		leds[3] <= packet_ready;
		leds[7] <= 1;
	end
		
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Logic analyzer


endmodule
